/* eslint-disable camelcase */

const f_forbidden = 0b1
const f_access = 0b10
const f_visible = 0b100
const f_preview = 0b1000
const f_download = 0b10000
const f_print = 0b100000
const f_upload = 0b1000000
const f_create = 0b10000000
const f_delete = 0b100000000
const f_rename = 0b1000000000
const f_move = 0b10000000000
const f_copy = 0b100000000000
const f_link = 0b1000000000000
const f_authorize = 0b10000000000000
const f_edit = 0b100000000000000

const map = {
  forbidden: f_forbidden,
  access: f_access,
  visible: f_visible,
  preview: f_preview,
  download: f_download,
  print: f_print,
  upload: f_upload,
  create: f_create,
  delete: f_delete,
  rename: f_rename,
  move: f_move,
  copy: f_copy,
  link: f_link,
  authorize: f_authorize,
  edit: f_edit
}

export class Permission {
  constructor (umask: number) {
    Object.entries(map).forEach(([k, v]: any) => {
      (this as any)[k] = (umask & v) === v
    })
    // this.forbidden = (umask & f_forbidden) == f_forbidden
    // this.access = (umask & f_access) == f_access
    // this.visible = (umask & f_visible) == f_visible
    // this.preview = (umask & f_preview) == f_preview
    // this.download = (umask & f_download) == f_download
    // this.print = (umask & f_print) == f_print
    // this.upload = (umask & f_upload) == f_upload
    // this.create = (umask & f_create) == f_create
    // this.delete = (umask & f_delete) == f_delete
    // this.rename = (umask & f_rename) == f_rename
    // this.move = (umask & f_move) == f_move
    // this.copy = (umask & f_copy) == f_copy
  }

  // 禁用
  forbidden = false

  // 可访问权限，即文件夹轨迹
  access = false

  // 可见权限
  visible = false

  // 可预览权限
  preview = false

  // 可下载权限
  download = false

  // 可打印权限
  print = false

  // 可上传权限
  upload = false

  // 可新建权限
  create = false

  // 可删除权限
  delete = false

  // 可重命名权限
  rename = false

  // 可移动权限
  move = false

  // 可复制权限
  copy = false

  // 可创建外链权限
  link = false

  // 可授权权限
  authorize = false

  // 可编辑权限
  edit = false

  set l_forbidden (value: boolean) {
    Object.entries(map).forEach(([k, v]: any) => {
      if (k.startsWith('l')) return
      (this as any)[k] = false
    })
    this.forbidden = value
  }

  get l_forbidden () {
    return this.forbidden
  }

  set l_visible (value: boolean) {
    if (!value) {
      Object.entries(map).forEach(([k, v]: any) => {
        if (k.startsWith('l_')) return
        (this as any)[k] = false
      })
    } else {
      this.visible = true
      this.forbidden = false
    }
  }

  get l_visible () {
    return this.visible
  }

  set l_preview (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    } else {
      this.edit = false
    }
    this.preview = value
  }

  get l_preview () {
    return this.preview
  }

  set l_download (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.download = value
  }

  get l_download () {
    return this.download
  }

  set l_print (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.print = value
  }

  get l_print () {
    return this.print
  }

  set l_upload (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.upload = value
  }

  get l_upload () {
    return this.upload
  }

  set l_create (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.create = value
  }

  get l_create () {
    return this.create
  }

  set l_delete (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.delete = value
  }

  get l_delete () {
    return this.delete
  }

  set l_rename (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.rename = value
  }

  get l_rename () {
    return this.rename
  }

  set l_move (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.move = value
  }

  get l_move () {
    return this.move
  }

  set l_copy (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.copy = value
  }

  get l_copy () {
    return this.copy
  }

  set l_link (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.link = value
  }

  get l_link () {
    return this.link
  }

  set l_authorize (value: boolean) {
    if (value) {
      this.visible = value
      this.forbidden = false
    }
    this.authorize = value
  }

  get l_authorize () {
    return this.authorize
  }

  set l_edit (value: boolean) {
    if (value) {
      this.visible = value
      this.preview = value
      this.forbidden = false
    }
    this.edit = value
  }

  get l_edit () {
    return this.edit
  }

  toUmask (): number {
    return Object.entries(map)
      .filter(([k, v]: any) => (this as any)[k])
      .map(v => v[1])
      .reduce((t, n) => t | n, 0)
  }
}

export const items = [
  { label: '禁用', value: 'forbidden' },
  { label: '可见', value: 'visible' },
  { label: '预览', value: 'preview' },
  { label: '下载', value: 'download' },
  { label: '打印', value: 'print' },
  { label: '上传', value: 'upload' },
  { label: '新建', value: 'create' },
  { label: '编辑', value: 'edit' },
  { label: '删除', value: 'delete' },
  { label: '重命名', value: 'rename' },
  { label: '移动', value: 'move' },
  { label: '复制', value: 'copy' },
  { label: '外链', value: 'link' },
  { label: '授权', value: 'authorize' }
]

// export const groups = [
//   { label: '仅可见者', value: f_visible },
//   { label: '预览者', value: f_visible | f_preview },
//   { label: '上传者', value: f_visible | f_preview | f_upload | f_download | f_create | f_link },
//   { label: '下载者', value: f_visible | f_preview | f_download },
//   { label: '编辑者', value: f_visible | f_preview | f_upload | f_download | f_create | f_rename | f_delete | f_copy | f_link },
//   { label: '无删除编辑者', value: f_visible | f_preview | f_upload | f_download | f_create | f_rename | f_copy | f_link },
//   { label: '禁止访问', value: f_forbidden }
// ]

export type PermissionName = 'visible' | 'preview' | 'download' | 'print' | 'upload' | 'create' | 'delete' | 'rename' | 'move' | 'copy' | 'link' | 'authorize' | 'edit';

export function hasPerm (name: PermissionName, ...docs: any[]) {
  return !docs.some(v => {
    if (v?.privilege && !v?.privilege?.none) return false
    const permission = v?.permission
    return !(permission && permission[name])
  })
}

export function getUmaskText (umask: number) {
  const p: any = new Permission(umask)
  return items.filter(v => p['l_' + v.value]).map(v => v.label).join(',')
}
